package mx.ipn.persistencia.mysql;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.util.ArrayList;
import java.util.Collection;

import mx.ipn.persistencia.dao.UsuarioDAO;
import mx.ipn.to.GrupoUsuarioTO;
import mx.ipn.to.UsuarioTO;

public class UsuarioDAOMySQL implements UsuarioDAO {
	static {
		FabricaDeDAOsMySQL.iniciaLog(UsuarioDAOMySQL.class);
	}

	private static final String llave = "sistema";

	private static final String INSERT = "INSERT INTO usuario (nombre_usuario,contrasenia,id_grupo_usuario,id_empleado,activo) VALUES(?,aes_encrypt(?,\""
			+ llave + "\"),?,?,?)";
	private static final String DELETE = "DELETE FROM cliente WHERE id_usuario=?";
	private static final String UPDATE = "UPDATE usuario SET nombre_usuario=?, contrasenia=aes_encrypt(?,\""
			+ llave
			+ "\"), id_grupo_usuario=?, id_empleado=?, activo=? WHERE id_usuario=?";
	private static final String ACTIVADESACTIVA = "UPDATE usuario SET activo=? WHERE id_usuario=?";

	private static final String FINDBYID = "SELECT id_usuario, nombre_usuario, aes_decrypt(contrasenia,\""
			+ llave
			+ "\") as contrasenia, id_grupo_usuario, id_empleado, activo FROM usuario WHERE id_usuario=? LIMIT 1";
	private static final String FINDBYEMPLEADO = "SELECT id_usuario, nombre_usuario, aes_decrypt(contrasenia,\""
			+ llave
			+ "\") as contrasenia, id_grupo_usuario, id_empleado, activo FROM usuario WHERE id_empleado=? LIMIT 1";
	private static final String FINDBYNOMBRE = "SELECT id_usuario, nombre_usuario, aes_decrypt(contrasenia,\""
			+ llave
			+ "\") as contrasenia, id_grupo_usuario, id_empleado, activo FROM usuario WHERE UPPER(REPLACE(nombre_usuario,' ','')) =UPPER(REPLACE(?,' ','')) LIMIT 1";

	private static final String SELECT = "SELECT id_usuario, nombre_usuario, aes_decrypt(contrasenia,\""
			+ llave
			+ "\") as contrasenia, id_grupo_usuario, id_empleado, activo FROM usuario";
	private static final String SELECTBYACTIVO = "SELECT id_usuario, nombre_usuario, aes_decrypt(contrasenia,\""
			+ llave
			+ "\") as contrasenia, id_grupo_usuario, id_empleado, activo FROM usuario WHERE activo=?";

	private static final String SELECTBYGRUPO = "SELECT id_usuario, nombre_usuario, aes_decrypt(contrasenia,\""
			+ llave
			+ "\") as contrasenia, id_grupo_usuario, id_empleado, activo FROM usuario WHERE id_grupo_usuario=?";

	@Override
	public short deleteUsuario(int idUsuario) {
		try {
			Connection conexion = FabricaDeDAOsMySQL.crearConexion();

			PreparedStatement ps = conexion.prepareStatement(DELETE);

			ps.setInt(1, idUsuario);

			ps.executeUpdate();

			if (ps.getUpdateCount() == 0) {
				ps.close();
				conexion.close();
				return 0;
			}

			else {
				ps.close();
				conexion.close();
				return 1;
			}
		} catch (Exception e) {
			e.printStackTrace();
			return (short) -1;
		}
	}

	@Override
	public short activaDesactivaUsuario(int idUsuario, boolean activo) {
		try {
			Connection conexion = FabricaDeDAOsMySQL.crearConexion();

			PreparedStatement ps = conexion.prepareStatement(ACTIVADESACTIVA);

			ps.setBoolean(1, activo);
			ps.setInt(2, idUsuario);

			ps.executeUpdate();

			if (ps.getUpdateCount() == 0) {
				ps.close();
				conexion.close();
				return 0;
			}

			else {
				ps.close();
				conexion.close();
				return 1;
			}
		} catch (Exception e) {
			e.printStackTrace();
			return (short) -1;
		}

	}

	@Override
	public UsuarioTO findUsuarioByEmpleado(int idEmpleado) {
		try {
			Connection conexion = FabricaDeDAOsMySQL.crearConexion();

			PreparedStatement ps = conexion.prepareStatement(FINDBYEMPLEADO);

			ps.setInt(1, idEmpleado);

			ResultSet rs = ps.executeQuery();

			if (rs.next()) {
				int idUsuario = rs.getInt("id_usuario");
				String nombreUsuario = rs.getString("nombre_usuario");
				String contrasenia = rs.getString("contrasenia");
				short idGrupoUsuario = rs.getShort("id_grupo_usuario");
				idEmpleado = rs.getInt("id_empleado");
				boolean activo = rs.getBoolean("activo");

				GrupoUsuarioDAOMySQL grupoUsuarioDAOMySQL = new GrupoUsuarioDAOMySQL();
				GrupoUsuarioTO grupoUsuarioTO = grupoUsuarioDAOMySQL
						.findGrupoUsuarioById(idGrupoUsuario);

				UsuarioTO usuarioTO = new UsuarioTO(idUsuario, nombreUsuario,
						contrasenia, grupoUsuarioTO, idEmpleado, activo);

				ps.close();
				conexion.close();
				return usuarioTO;
			}

			ps.close();
			conexion.close();
			return null;

		} catch (Exception e) {
			e.printStackTrace();
			return null;
		}
	}

	@Override
	public UsuarioTO findUsuarioById(int idUsuario) {
		try {
			Connection conexion = FabricaDeDAOsMySQL.crearConexion();

			PreparedStatement ps = conexion.prepareStatement(FINDBYID);

			ps.setInt(1, idUsuario);

			ResultSet rs = ps.executeQuery();

			if (rs.next()) {
				idUsuario = rs.getInt("id_usuario");
				String nombreUsuario = rs.getString("nombre_usuario");
				String contrasenia = rs.getString("contrasenia");
				short idGrupoUsuario = rs.getShort("id_grupo_usuario");
				int idEmpleado = rs.getInt("id_empleado");
				boolean activo = rs.getBoolean("activo");

				GrupoUsuarioDAOMySQL grupoUsuarioDAOMySQL = new GrupoUsuarioDAOMySQL();
				GrupoUsuarioTO grupoUsuarioTO = grupoUsuarioDAOMySQL
						.findGrupoUsuarioById(idGrupoUsuario);

				UsuarioTO usuarioTO = new UsuarioTO(idUsuario, nombreUsuario,
						contrasenia, grupoUsuarioTO, idEmpleado, activo);

				ps.close();
				conexion.close();
				return usuarioTO;
			}

			ps.close();
			conexion.close();
			return null;

		} catch (Exception e) {
			e.printStackTrace();
			return null;
		}
	}

	@Override
	public UsuarioTO findUsuarioByNombre(String nombreUsuario) {
		try {
			Connection conexion = FabricaDeDAOsMySQL.crearConexion();

			PreparedStatement ps = conexion.prepareStatement(FINDBYNOMBRE);

			ps.setString(1, nombreUsuario);

			ResultSet rs = ps.executeQuery();

			if (rs.next()) {
				int idUsuario = rs.getInt("id_usuario");
				nombreUsuario = rs.getString("nombre_usuario");
				String contrasenia = rs.getString("contrasenia");
				short idGrupoUsuario = rs.getShort("id_grupo_usuario");
				int idEmpleado = rs.getInt("id_empleado");
				boolean activo = rs.getBoolean("activo");

				GrupoUsuarioDAOMySQL grupoUsuarioDAOMySQL = new GrupoUsuarioDAOMySQL();
				GrupoUsuarioTO grupoUsuarioTO = grupoUsuarioDAOMySQL
						.findGrupoUsuarioById(idGrupoUsuario);

				UsuarioTO usuarioTO = new UsuarioTO(idUsuario, nombreUsuario,
						contrasenia, grupoUsuarioTO, idEmpleado, activo);

				ps.close();
				conexion.close();
				return usuarioTO;
			}

			ps.close();
			conexion.close();
			return null;

		} catch (Exception e) {
			e.printStackTrace();
			return null;
		}
	}

	@Override
	public int insertUsuario(UsuarioTO usuarioTO) {
		try {
			Connection conexion = FabricaDeDAOsMySQL.crearConexion();

			PreparedStatement ps = conexion.prepareStatement(INSERT);

			ps.setString(1, usuarioTO.getNombreUsuario());
			ps.setString(2, usuarioTO.getContrasenia());
			ps.setShort(3, usuarioTO.getGrupoUsuarioTO().getIdGrupoUsuario());
			ps.setInt(4, usuarioTO.getIdEmpleado());
			ps.setBoolean(5, usuarioTO.getActivo());

			ps.executeUpdate();

			// atrapa el indice del campo agregado
			int autoIncIndice = -1;
			ResultSet rs = ps.getGeneratedKeys();

			if (rs.next()) {
				autoIncIndice = rs.getInt(1);
			} else {
				System.err.print("No se pudo agregar campo");
				return 0;
			}

			ps.close();
			conexion.close();

			return autoIncIndice;
		} catch (Exception e) {
			e.printStackTrace();
			return -1;
		}
	}

	@Override
	public Collection<UsuarioTO> selectUsuarios() {
		try {
			Connection conexion = FabricaDeDAOsMySQL.crearConexion();

			PreparedStatement ps = conexion.prepareStatement(SELECT);

			ResultSet rs = ps.executeQuery();

			Collection<UsuarioTO> coleccion = null;

			while (rs.next()) {
				if (coleccion == null)
					coleccion = new ArrayList<UsuarioTO>();

				int idUsuario = rs.getInt("id_usuario");
				String nombreUsuario = rs.getString("nombre_usuario");
				String contrasenia = rs.getString("contrasenia");
				short idGrupoUsuario = rs.getShort("id_grupo_usuario");
				int idEmpleado = rs.getInt("id_empleado");
				boolean activo = rs.getBoolean("activo");

				GrupoUsuarioDAOMySQL grupoUsuarioDAOMySQL = new GrupoUsuarioDAOMySQL();
				GrupoUsuarioTO grupoUsuarioTO = grupoUsuarioDAOMySQL
						.findGrupoUsuarioById(idGrupoUsuario);

				UsuarioTO usuarioTO = new UsuarioTO(idUsuario, nombreUsuario,
						contrasenia, grupoUsuarioTO, idEmpleado, activo);

				coleccion.add(usuarioTO);
			}

			ps.close();
			conexion.close();
			return coleccion;

		} catch (Exception e) {
			e.printStackTrace();
			return null;
		}
	}

	@Override
	public Collection<UsuarioTO> selectUsuariosByActivo(boolean activo) {
		try {
			Connection conexion = FabricaDeDAOsMySQL.crearConexion();

			PreparedStatement ps = conexion.prepareStatement(SELECTBYACTIVO);

			ps.setBoolean(1, activo);

			ResultSet rs = ps.executeQuery();

			Collection<UsuarioTO> coleccion = null;

			while (rs.next()) {
				if (coleccion == null)
					coleccion = new ArrayList<UsuarioTO>();

				int idUsuario = rs.getInt("id_usuario");
				String nombreUsuario = rs.getString("nombre_usuario");
				String contrasenia = rs.getString("contrasenia");
				short idGrupoUsuario = rs.getShort("id_grupo_usuario");
				int idEmpleado = rs.getInt("id_empleado");

				GrupoUsuarioDAOMySQL grupoUsuarioDAOMySQL = new GrupoUsuarioDAOMySQL();
				GrupoUsuarioTO grupoUsuarioTO = grupoUsuarioDAOMySQL
						.findGrupoUsuarioById(idGrupoUsuario);

				UsuarioTO usuarioTO = new UsuarioTO(idUsuario, nombreUsuario,
						contrasenia, grupoUsuarioTO, idEmpleado, activo);

				coleccion.add(usuarioTO);
			}

			ps.close();
			conexion.close();
			return coleccion;

		} catch (Exception e) {
			e.printStackTrace();
			return null;
		}
	}

	@Override
	public Collection<UsuarioTO> selectUsuariosByGrupo(short idGrupo) {
		try {
			Connection conexion = FabricaDeDAOsMySQL.crearConexion();

			PreparedStatement ps = conexion.prepareStatement(SELECTBYGRUPO);

			ps.setShort(1, idGrupo);

			ResultSet rs = ps.executeQuery();

			Collection<UsuarioTO> coleccion = null;

			while (rs.next()) {
				if (coleccion == null)
					coleccion = new ArrayList<UsuarioTO>();

				int idUsuario = rs.getInt("id_usuario");
				String nombreUsuario = rs.getString("nombre_usuario");
				String contrasenia = rs.getString("contrasenia");
				short idGrupoUsuario = rs.getShort("id_grupo_usuario");
				int idEmpleado = rs.getInt("id_empleado");
				boolean activo = rs.getBoolean("activo");

				GrupoUsuarioDAOMySQL grupoUsuarioDAOMySQL = new GrupoUsuarioDAOMySQL();
				GrupoUsuarioTO grupoUsuarioTO = grupoUsuarioDAOMySQL
						.findGrupoUsuarioById(idGrupoUsuario);

				UsuarioTO usuarioTO = new UsuarioTO(idUsuario, nombreUsuario,
						contrasenia, grupoUsuarioTO, idEmpleado, activo);

				coleccion.add(usuarioTO);
			}

			ps.close();
			conexion.close();

			return coleccion;

		} catch (Exception e) {
			e.printStackTrace();
			return null;
		}
	}

	@Override
	public short updateUsuario(UsuarioTO usuarioTO) {
		try {
			Connection conexion = FabricaDeDAOsMySQL.crearConexion();

			PreparedStatement ps = conexion.prepareStatement(UPDATE);

			ps.setString(1, usuarioTO.getNombreUsuario());
			ps.setString(2, usuarioTO.getContrasenia());
			ps.setShort(3, usuarioTO.getGrupoUsuarioTO().getIdGrupoUsuario());
			ps.setInt(4, usuarioTO.getIdEmpleado());
			ps.setBoolean(5, usuarioTO.getActivo());
			ps.setInt(6, usuarioTO.getIdUsuario());

			ps.executeUpdate();

			if (ps.getUpdateCount() == 0) {
				ps.close();
				conexion.close();
				return 0;
			}

			else {
				ps.close();
				conexion.close();
				return 1;
			}
		} catch (Exception e) {
			e.printStackTrace();
			return (short) -1;
		}
	}

}
